import websocket
import datetime
import hashlib
import base64
import hmac
import json
from urllib.parse import urlencode
import time
import ssl
from wsgiref.handlers import format_date_time
from datetime import datetime
from time import mktime
import _thread as thread
import os
from dotenv import load_dotenv


env_path = os.path.join(os.path.dirname(__file__), '..', 'ak.envs')
load_dotenv(dotenv_path=env_path)

STATUS_FIRST_FRAME = 0
STATUS_CONTINUE_FRAME = 1
STATUS_LAST_FRAME = 2

class Ws_Param(object):
    def __init__(self, APPID, APIKey, APISecret, Text, language='chinese'):
        self.APPID = APPID
        self.APIKey = APIKey
        self.APISecret = APISecret
        self.Text = Text

        self.CommonArgs = {"app_id": self.APPID}


        if language == 'french':

            vcn = "x2_FrRgM_Lisa"
        else:

            vcn = "x4_yezi"

        self.BusinessArgs = {
            "aue": "lame",
            "auf": "audio/L16;rate=16000",
            "vcn": vcn,
            "tte": "utf8"
        }
        self.Data = {"status": 2, "text": str(base64.b64encode(self.Text.encode('utf-8')), "UTF8")}

    def create_url(self):
        url = 'wss://tts-api.xfyun.cn/v2/tts'
        now = datetime.now()
        date = format_date_time(mktime(now.timetuple()))

        signature_origin = "host: " + "tts-api.xfyun.cn" + "\n"
        signature_origin += "date: " + date + "\n"
        signature_origin += "GET " + "/v2/tts " + "HTTP/1.1"

        signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
                                digestmod=hashlib.sha256).digest()
        signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')

        authorization_origin = "api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"" % (
            self.APIKey, "hmac-sha256", "host date request-line", signature_sha)
        authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')

        v = {
            "authorization": authorization,
            "date": date,
            "host": "tts-api.xfyun.cn"
        }
        url = url + '?' + urlencode(v)
        return url


def text_to_speech(text, output_path, language='chinese'):
    global wsParam, output_file, tts_success, char_count

    output_file = output_path
    tts_success = False
    char_count = len(text)

    def on_message(ws, message):
        global tts_success
        try:
            message_json = json.loads(message)
            code = message_json["code"]
            sid = message_json["sid"]
            audio = message_json["data"]["audio"]
            audio_data = base64.b64decode(audio)
            status = message_json["data"]["status"]

            if code != 0:
                errMsg = message_json["message"]
                print(f"❌ TTS错误：{errMsg} (code:{code})")
                ws.close()
            else:
                with open(output_file, 'ab') as f:
                    f.write(audio_data)

            if status == 2:
                print(f"✅ 语音生成完成：{output_file}")
                tts_success = True
                ws.close()

        except Exception as e:
            print(f"❌ TTS消息处理异常：{e}")

    def on_error(ws, error):
        print(f"❌ TTS连接错误：{error}")

    def on_close(ws, close_status_code, close_msg):
        pass

    def on_open(ws):
        def run(*args):
            d = {
                "common": wsParam.CommonArgs,
                "business": wsParam.BusinessArgs,
                "data": wsParam.Data,
            }
            d = json.dumps(d)
            ws.send(d)

            if os.path.exists(output_file):
                os.remove(output_file)

        thread.start_new_thread(run, ())


    wsParam = Ws_Param(
        APPID=os.getenv('XFYUN_APPID'),
        APISecret=os.getenv('XFYUN_API_SECRET'),
        APIKey=os.getenv('XFYUN_API_KEY'),
        Text=text,
        language=language
    )

    websocket.enableTrace(False)
    wsUrl = wsParam.create_url()
    ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close)
    ws.on_open = on_open
    ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})

    return tts_success, char_count
